/****************************************************************************/
/*                                                                          */
/*   FILE:    sesstat.c   	                                                */
/*   DATE:    30/06/97                                                      */
/*   PURPOSE: DVB-CI Session layer - state diagram for SESSION task			*/
/*   TAB STOPS : 4                       */
/*   HISTORY:                                                               */
/*   Version    Date  		    Written by	     Notes                  */
/*	 1.0	    30/06/1997      SCM              Initial implementation */
/*   1.5        28/12/1998      SCM              In function SESS_NotOpen() */
/*                                            add:   return iRet;           */
/*                                                                    	    */
/*--------------------------------------------------------------------------*/
/*   GENERAL COMMENTS                                                 	    */
/*																		    */
/****************************************************************************/
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include "sm_trace.h"
#include "itc.h"
#include "session.h"            /* Main Module			  	*/



/*--------------------------------------------------------------------------*/
/* External Variables		                                            	*/
/*--------------------------------------------------------------------------*/
extern sess_t g_ses_tab_ssnb[];   /* ssnb table   								*/

/* ======================================================================== */
/* NAME : SESS_Action					 									*/
/* 									    									*/
/* DESCRIPTION : Activate the action associated to the current state 		*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram				*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
void SESS_Action(int ssnbIndex, xmsg_t* pXmsg)			    
{
	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Action() - entry,ssnbIndex=%d\r\n",ssnbIndex);

	SM_TRACE_INFO(TRMOD_SESS,"SESS_Action() - ssnbIndex=%d,cur_state=%s(%d),"
			"tcid=%d,ssnb=%d,rtcid=%d,rssnb=%d,timerId=0x%02X\r\n", 
		ssnbIndex,
		GETSESSSTATNAME(g_ses_tab_ssnb[ssnbIndex].m_state), g_ses_tab_ssnb[ssnbIndex].m_state,
		g_ses_tab_ssnb[ssnbIndex].m_tcid, g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
		g_ses_tab_ssnb[ssnbIndex].m_rtcid, g_ses_tab_ssnb[ssnbIndex].m_rssnb, 
		g_ses_tab_ssnb[ssnbIndex].m_timerId);

	switch(g_ses_tab_ssnb[ssnbIndex].m_state)
	{
	case SESS_IDLE : 
		SESS_Idle(ssnbIndex, pXmsg);
		break;
			
	case SESS_OPEN : 
		SESS_Open(ssnbIndex, pXmsg);
		break;

	case SESS_ACTIVE : 
		SESS_Active(ssnbIndex, pXmsg);
		break;
			
	case SESS_CREATION : 
		SESS_Creation(ssnbIndex, pXmsg);
		break;			
			
	case SESS_CLOSE :  
		SESS_Close(ssnbIndex, pXmsg);
		break;
			
	case SESS_RELEASE :  
		SESS_Release(ssnbIndex, pXmsg);
		break;
			
	case SESS_DELETION :  
		SESS_Deletion(ssnbIndex, pXmsg);
		break;
			
	default: 
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Action() - Unknown state %d\r\n", 
					g_ses_tab_ssnb[ssnbIndex].m_state);
		break;
	}

	SM_TRACE_INFO(TRMOD_SESS,"SESS_Action() - ssnbIndex=%d,cur_state=%s(%d),"
			"tcid=%d,ssnb=%d,rtcid=%d,rssnb=%d,timerId=0x%02X\r\n", 
			ssnbIndex,
			GETSESSSTATNAME(g_ses_tab_ssnb[ssnbIndex].m_state), g_ses_tab_ssnb[ssnbIndex].m_state,
			g_ses_tab_ssnb[ssnbIndex].m_tcid, g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
			g_ses_tab_ssnb[ssnbIndex].m_rtcid, g_ses_tab_ssnb[ssnbIndex].m_rssnb, 
			g_ses_tab_ssnb[ssnbIndex].m_timerId);

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Action() - return\r\n");
}

                                                                          
	

/* ======================================================================== */
/* NAME : SESS_Idle								 							*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the SESS_IDLE state						*/
/*		There is a new transport connection . The SESS Task is waiting for 	*/
/*		a session opening on this new tcid									*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram				*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_Idle(int ssnbIndex, xmsg_t* pXmsg)
{                                                                          
	int				iRet;
	xmsg_t			xmsg;
	unsigned char 	evt = 0;
	xpdu_t		xpduRcv;

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Idle() - entry,ssnbIndex=%d\r\n", ssnbIndex);

	evt = pXmsg->m_type;
	if (SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_SESS, "SESS_Idle() - received evt=%s(0x%02X),ssnbIndex=%d\r\n", 
					XMSG_NAME(evt), evt, ssnbIndex);

	switch(evt)
	{                                   
	case dutag_open_session_request :
		/* Forward the open session request to the RM Task */
		/* =============================================== */	
		/* Take the same memory buffer */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_sndrcver = (SESS << 4) | RM;
		xmsg.m_type  = RM_OPEN_SS_REQ;
		xmsg.m_bd.m_rm_open_ss_req.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;		/* Use by RM resource to assign tcid to resources declared on a module */
		xmsg.m_bd.m_rm_open_ss_req.m_ssnb = g_ses_tab_ssnb[ssnbIndex].m_ssnb;
        xmsg.m_bd.m_rm_open_ss_req.m_ressId = xpduRcv.m_du.m_xpdu_open_session_request.m_ressId;

		/* Send the message */
   		if (!ITC_SendXmsg(&xmsg))
   		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Idle() - Can't send the RM_OPEN_SS_REQ message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
			iRet = 0;		/* Error */
		}
		else
		{
			/* Save the ress_id */
           	g_ses_tab_ssnb[ssnbIndex].m_ressId = xmsg.m_bd.m_rm_open_ss_req.m_ressId;
				
		   	/* Set the new state */
			g_ses_tab_ssnb[ssnbIndex].m_state = SESS_OPEN;
			iRet = 1;		/* Success; keep the memory  */
		}
		break;		/* end of open_session_request processing */
	
	case RM_OPEN_SS_REQ: //add by pmy
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Idle() - RM_OPEN_SS_REQ only for module\r\n");
		break;	
	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Idle() - protocol error . event %d received in %d state\r\n", evt, g_ses_tab_ssnb[ssnbIndex].m_state);
		iRet = 1;
		break;			
	} //end switch

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Idle() - return,iRet=%d\r\n", iRet);
	return iRet;
}	/* end of SESS_IDLE state */
	


/* ======================================================================== */
/* NAME : SESS_Open			 												*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the SESS_OPEN state						*/
/*		- The SESS Task is waiting for a response of the RM Task for the	*/
/*		open session request from the module								*/
/*		- If the resource is on a distant module, the Task performs the		*/
/*		routing with session creation										*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram					*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_Open(int ssnbIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;		/* return code  											*/
	xpdu_t xpdu;
	xmsg_t		xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Open() - entry,ssnbIndex=%d\r\n", ssnbIndex);
	
	evt = pXmsg->m_type;
	if (SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_SESS, "SESS_Open() - received evt=%s(0x%02X),ssnbIndex=%d\r\n", 
					XMSG_NAME(evt), evt, ssnbIndex);

	iRet = 1;
	
	switch(evt) 
	{                                   
	case RM_OPEN_SS_RSP :
		/* Get free buffer for SPDU message : the message is open_session_response or create_session */
		/* the greater size is the open_session_response size */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(OPEN_SESSION_RESPONSE_SIZE);
		if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - can't allocate buffer for coding SPDU\r\n");
			return 1;	/* Error but return = 1 since no memory to free */
		}

		if (pXmsg->m_bd.m_rm_open_ss_rsp.m_rtcid)
		{	
			/* the resource is on a DVB distant module ; routing is the tcid of the distant module */
			/* =================================================================================== */
				
			/* Get a new session number for the routing tcid */
			iRet = SESS_RoutSsnb(g_ses_tab_ssnb[ssnbIndex].m_ssnb, pXmsg->m_bd.m_rm_open_ss_rsp.m_rtcid);
			if (iRet < 0)
			{	
				/* can't open the distant session ; close the first part of the session */
				/* ==================================================================== */
				xpdu.m_du.m_xpdu_open_session_response.m_status = SS_NOTAVAILABLE;
       	        xpdu.m_du.m_xpdu_open_session_response.m_ressId = pXmsg->m_bd.m_rm_open_ss_rsp.m_ressId;
				
				xmsg.m_sndrcver = (SESS << 4) | TRANS;
				xmsg.m_type  = SPDU;
				xmsg.m_bd.m_spdu.m_tcid= g_ses_tab_ssnb[ssnbIndex].m_tcid;
				xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_open_session_response, 
											g_ses_tab_ssnb[ssnbIndex].m_ssnb,
											&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    			if (xmsg.m_bd.m_spdu.m_len <= 0) 
    			{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - Can't code an open_session_response for 0x%08X\r\n", 
									xpdu.m_du.m_xpdu_open_session_response.m_ressId);
					FreeXmsg(&xmsg);
					return 0;		/* Error */
				}	
            
    			if (!ITC_SendXmsg(&xmsg))
    			{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - Can't send the open_session_response message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
					iRet = 0;		/* Error */
				}
				else
				{
					/* Set the new state */
					g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
					iRet = 1;		/* Success; keep the memory  */
				}
			}
			else
			{	
				/* create the second link of the distributed session */
				/* ================================================= */
    	        xpdu.m_du.m_xpdu_create_session_request.m_ressId = pXmsg->m_bd.m_rm_open_ss_rsp.m_ressId;
				
				xmsg.m_sndrcver = (SESS << 4) | TRANS;
				xmsg.m_type  = SPDU;
				xmsg.m_bd.m_spdu.m_tcid= pXmsg->m_bd.m_rm_open_ss_rsp.m_rtcid;
				xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_create_session_request, g_ses_tab_ssnb[ssnbIndex].m_rssnb,
											&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    			if (xmsg.m_bd.m_spdu.m_len <= 0) 
    			{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - Can't code a create_session for 0x%08X\r\n", 
									xpdu.m_du.m_xpdu_create_session_request.m_ressId);
					FreeXmsg(&xmsg);
					return 0;		/* Error */
				}	
            
				/* Send the message */
    			if (!ITC_SendXmsg(&xmsg))
    			{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - Can't send the create_session message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
					FreeXmsg(&xmsg);
					iRet = 0;		/* Error */
				}
				else
				{
					/* Set the timer waiting for the response for this ssnb */
					g_ses_tab_ssnb[ssnbIndex].m_timerId = SESS_SetTimer(SESS_TIMEOUT);/* do nothing if the timer can't be created */
			
    				/* Set the new state */
					g_ses_tab_ssnb[ssnbIndex].m_state = SESS_CREATION;
					iRet = 1;		/* Success; keep the memory  */
				}
			}
		}
		else
		{	
			/* the resource is on the local host */
			/* ================================= */
			xpdu.m_du.m_xpdu_open_session_response.m_status = pXmsg->m_bd.m_rm_open_ss_rsp.m_status;
   	        xpdu.m_du.m_xpdu_open_session_response.m_ressId = pXmsg->m_bd.m_rm_open_ss_rsp.m_ressId;

			/* Send the open session response to the TRANS Task */
			/* ================================================ */	
			xmsg.m_sndrcver = (SESS << 4) | TRANS;
			xmsg.m_type  = SPDU;
			xmsg.m_bd.m_spdu.m_tcid= g_ses_tab_ssnb[ssnbIndex].m_tcid;
			xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_open_session_response, 
									g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
									&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    		if (xmsg.m_bd.m_spdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - Can't code an open_session_response for 0x%08X\r\n", 
								xpdu.m_du.m_xpdu_open_session_response.m_ressId);
				FreeXmsg(&xmsg);
				return 0;		/* Error */
			}	
            
			/* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - Can't send the open_session_response message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
				FreeXmsg(&xmsg);
				iRet = 0;		/* Error */
			}
			else
			{                                   
				if (pXmsg->m_bd.m_rm_open_ss_rsp.m_status == SS_OK)
				{
					/* Send a RM_SS_OPENED to the RM Task */
					/* ================================== */
					memset(&xmsg, 0x00, sizeof(xmsg));
					xmsg.m_sndrcver    = (SESS << 4) | RM;
					xmsg.m_type     = RM_SS_OPENED;
            		xmsg.m_bd.m_rm_ss_opened.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;
					xmsg.m_bd.m_rm_ss_opened.m_ssnb = g_ses_tab_ssnb[ssnbIndex].m_ssnb;            

			   		/* Send the message */
    				if (!ITC_SendXmsg(&xmsg))
    				{
						SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - Can't send the RM_SS_OPENED message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
						FreeXmsg(&xmsg);
						iRet = 0;		/* Error */
					}
					else
					{
				    	/* Set the new state */
						g_ses_tab_ssnb[ssnbIndex].m_state = SESS_ACTIVE;
						iRet = 1;		/* Success; keep the memory  */
					}
				}
				else
				{	
					/* open_session_response(-) sent */
				    /* Set the new state */
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - open session response status is 0x%02X\r\n",
									pXmsg->m_bd.m_rm_open_ss_rsp.m_status);
					g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
					iRet = 1;		/* Success; keep the memory  */
				}	
			}
		}	
		break;		/* end of open_session_request processing */

	case dutag_open_session_response:   //add by pmy
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - open ssession response only for module\r\n");
		iRet = 0;
		break;
	case SS_TC_DELETED :						
	   	/* Set the new state */
		g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
		break;	/* end of SS_TC_DELETED processing */

	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Open() - protocol error . event %d received in %d state\r\n", evt, g_ses_tab_ssnb[ssnbIndex].m_state);
		iRet = 1;
		break;			
	}

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Open() - return,iRet=%d\r\n", iRet);
	return iRet;
}	/* end of SESS_OPEN state */
	

/* ======================================================================== */
/* NAME : SESS_Active		 												*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the SESS_ACTIVE state						*/
/*		- The SESS Task is waiting for APDU to send to the module 			*/
/*		- The SESS Task is waiting for SPDU to send to the local or distant */
/*		(routing) resource													*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram					*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_Active(int ssnbIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;		/* return code  											*/
	xpdu_t xpdu;	/* information for SPDU		 								*/
	unsigned short ssnb;	/* current ssnb										*/
	unsigned char tcid;		/* current tcid										*/
	xmsg_t		xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Active() - entry,ssnbIndex=%d\r\n", ssnbIndex);
	
	evt = pXmsg->m_type;
	if (SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_SESS, "SESS_Active() - received evt=%s(0x%02X),ssnbIndex=%d\r\n", 
					XMSG_NAME(evt), evt, ssnbIndex);

	switch(evt)
	{                                   
	case APDU :                                               
		/* Code the SPDU and Send it to the TRANS Task */
		/* =========================================== */
		/* Get a new free buffer for SPDU message (pXmsg points the APDU) */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc((unsigned short)(pXmsg->m_bd.m_apdu.m_len + SESSION_NUMBER_SIZE));
		if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - can't allocate buffer for coding SPDU\r\n");
			return 0;	/* Error */
		}

		/* Assign pointer to APDU buffer */				
		xpdu.m_du.m_xpdu_session_number.m_pbData = pXmsg->m_bd.m_apdu.m_pbApdu;
		xpdu.m_du.m_xpdu_session_number.m_len   = pXmsg->m_bd.m_apdu.m_len;
					
		xmsg.m_sndrcver = (SESS << 4) | TRANS;
		xmsg.m_type  = SPDU;
		xmsg.m_bd.m_spdu.m_tcid= g_ses_tab_ssnb[ssnbIndex].m_tcid;			       	     
		xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_session_number,
								g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
								&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    	if (xmsg.m_bd.m_spdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't code a session_number for %d ssnb\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb); 
			FreeXmsg(&xmsg);
			return 0;		/* Error */
		}	
				
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the SPDU message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
			FreeXmsg(&xmsg);
			iRet = 0;		/* Error */
		}                              
		else
		{
			iRet = 1;	
		}
						
		break;	/* end of APDU processing */
			
	case dutag_session_number:
		if (g_ses_tab_ssnb[ssnbIndex].m_rssnb == 0)
		{	
			/* decode the SPDU and send the APDU to the RM Task */
			/* ================================================ */
			/* Get a new free buffer for APDU message (pXmsg points the SPDU) */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_apdu.m_pbApdu = ITC_DynAlloc(xpduRcv.m_du.m_xpdu_session_number.m_len);
			if (xmsg.m_bd.m_apdu.m_pbApdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - can't allocate buffer for coding APDU\r\n");
				return 0;	/* Error */
			}
					
			xmsg.m_sndrcver = (SESS << 4) | RM;
			xmsg.m_type  = APDU;
			xmsg.m_bd.m_apdu.m_ssnb= g_ses_tab_ssnb[ssnbIndex].m_ssnb;			       	     
			xmsg.m_bd.m_apdu.m_len = xpduRcv.m_du.m_xpdu_session_number.m_len;				       	     
			memcpy(xmsg.m_bd.m_apdu.m_pbApdu, xpduRcv.m_du.m_xpdu_session_number.m_pbData, 
						xmsg.m_bd.m_apdu.m_len);
				
			/* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the APDU message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
				FreeXmsg(&xmsg);
				iRet = 0;		/* Error */
			}                              
			else
			{
				iRet = 1;
			}
		}
		else
		{	
			/* Foward the SPDU on the second part of the session (ssnb or rssnb) */
			/* =================================================				 */
			if (xpduRcv.m_du.m_xpdu_session_number.m_ssnb == g_ses_tab_ssnb[ssnbIndex].m_rssnb)
			{
				pXmsg->m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;	/* send to the first part  */		       	     	
				SESS_CodSsnb( g_ses_tab_ssnb[ssnbIndex].m_ssnb, pXmsg->m_bd.m_spdu.m_pbSpdu+2);
				ssnb = g_ses_tab_ssnb[ssnbIndex].m_ssnb;
			}	
			else
			{
				pXmsg->m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_rtcid;	/* send to the second part */		       	     			       	     
				SESS_CodSsnb( g_ses_tab_ssnb[ssnbIndex].m_rssnb, pXmsg->m_bd.m_spdu.m_pbSpdu+2);
				ssnb = g_ses_tab_ssnb[ssnbIndex].m_rssnb;
			}	

			pXmsg->m_sndrcver = (SESS << 4) | TRANS;

			/* Send the message */
    		if (!ITC_SendXmsg(pXmsg))
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the SPDU message for %d ssnb to RM Task\r\n", ssnb);
				iRet = 0;		/* Error */
			}                              
			else 
			{
				pXmsg->m_bd.m_spdu.m_pbSpdu = NULL; //add by pmy
				iRet = 1;		/* Success			*/
			}
		}
		break;	/* end of dutag_session_number processing */
			
	case dutag_close_session_request :    
		if (g_ses_tab_ssnb[ssnbIndex].m_rssnb == 0)
		{	
			/* Send the response and send a RM_SS_CLOSED to the RM Task */
			/* ======================================================== */ 

			/* re-allocate memory since close_session_response size greater than close_session_request size */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynReAlloc(xmsg.m_bd.m_spdu.m_pbSpdu, CLOSE_SESSION_RESPONSE_SIZE);

			if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - can't re-allocate buffer for coding SPDU\r\n");
				return 0;	/* Error */
			}

			xpdu.m_du.m_xpdu_close_session_response.m_status = SS_OK;
				
			xmsg.m_sndrcver = (SESS << 4) | TRANS;
			xmsg.m_type  = SPDU;
			xmsg.m_bd.m_spdu.m_tcid= g_ses_tab_ssnb[ssnbIndex].m_tcid;
			xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_close_session_response,
									g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
									&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    		if (xmsg.m_bd.m_spdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't code an open_session_response for %d ssnb\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb); 
				return 0;		/* Error */
			}	
            
			/* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the open_session_response message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
				FreeXmsg(&xmsg);
				iRet = 0;		/* Error */
			}
			else
			{
				/* forward the closing to the RM Task with RM_SS_CLOSED */
				/* ==================================================== */
				memset(&xmsg, 0x00, sizeof(xmsg));
				xmsg.m_sndrcver 	 = (SESS << 4) | RM;
				xmsg.m_type  	 = RM_SS_CLOSED;
				xmsg.m_bd.m_rm_ss_closed.m_ssnb   = g_ses_tab_ssnb[ssnbIndex].m_ssnb;
				xmsg.m_bd.m_rm_ss_closed.m_status = SS_OK;
						
				/* Send the message */
    			if (!ITC_SendXmsg(&xmsg))
    			{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the RM_SS_CLOSED message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
					iRet = 0;		/* Error */
				}
                
	            /* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
				iRet = 1;		/* Success */
			}
		}
		else
		{   
			/* Forward the close session request toward the other side of the session */          
			/* ====================================================================== */
			pXmsg->m_sndrcver 		= (SESS << 4) | TRANS;
			pXmsg->m_type  		= SPDU;
			/* Update the receiver (tcid ant ssnb) */						
			if (xpduRcv.m_du.m_xpdu_close_session_request.m_ssnb == g_ses_tab_ssnb[ssnbIndex].m_rssnb)
			{
				pXmsg->m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;	/* send to the first part  */		       	     	
				SESS_CodSsnb( g_ses_tab_ssnb[ssnbIndex].m_ssnb, pXmsg->m_bd.m_spdu.m_pbSpdu+2);

				/* reverse the (tcid,ssnb) / (rtcid, rssnb) in order to assign the	   */
				/* closing part in the (tcid, ssnb) for response management			   */
				/* cf SESS_Close when receiving a SS_TC_DELETED						   */
				ssnb = g_ses_tab_ssnb[ssnbIndex].m_rssnb;
				tcid = g_ses_tab_ssnb[ssnbIndex].m_rtcid;
				g_ses_tab_ssnb[ssnbIndex].m_rssnb = g_ses_tab_ssnb[ssnbIndex].m_ssnb;
				g_ses_tab_ssnb[ssnbIndex].m_rtcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;
				g_ses_tab_ssnb[ssnbIndex].m_ssnb = ssnb;
				g_ses_tab_ssnb[ssnbIndex].m_tcid = tcid;;
			}                                                            
			else
			{
				pXmsg->m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_rtcid;	/* send to the second part */		       	     	
				SESS_CodSsnb( g_ses_tab_ssnb[ssnbIndex].m_rssnb, pXmsg->m_bd.m_spdu.m_pbSpdu+2);
			}   

			/* Send the message */
   			if (!ITC_SendXmsg(pXmsg))
   			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the close_session_request message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
				iRet = 0;		/* Error */
			}
            else
            {
				pXmsg->m_bd.m_spdu.m_pbSpdu = NULL;
               	/* Set the timer waiting for the response for this ssnb */
				g_ses_tab_ssnb[ssnbIndex].m_timerId = SESS_SetTimer(SESS_TIMEOUT);/* do nothing if the timer can't be created */
					
				/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_CLOSE;
				iRet = 1;		/* Success */
			}	
		}
		break;	/* end of close_session_request processing */
			
	case RM_CLOSE_SS :
		/* Send the close session request to the TRANS Task */
		/* ================================================ */
		/* Get a buffer for SPDU message */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(CLOSE_SESSION_REQUEST_SIZE);
		if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - can't allocate buffer for coding SPDU\r\n");
			return 1;		/* Error but return = 1 since no allocated memory to free */
		}
				
		xpdu.m_du.m_xpdu_close_session_response.m_status = SS_OK;
					
		xmsg.m_sndrcver = (SESS << 4) | TRANS;
		xmsg.m_type  = SPDU;
		xmsg.m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;
		xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_close_session_request,
								g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
								&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
		if (xmsg.m_bd.m_spdu.m_len <= 0) 
		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't code a close_session_request for %d ssnb\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb); 
			return 0;	/* Error */
		}	
            
		/* Send the message */
		if (!ITC_SendXmsg(&xmsg))
		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the close_session_request message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
			FreeXmsg(&xmsg);
			return 0;	/* Error */
		}
		else
		{
           	/* Set the timer waiting for the response for this ssnb */
			g_ses_tab_ssnb[ssnbIndex].m_timerId = SESS_SetTimer(SESS_TIMEOUT);/* do nothing if the timer can't be created */
					
			/* Set the new state */
			g_ses_tab_ssnb[ssnbIndex].m_state = SESS_CLOSE;
			iRet = 1;		/* Success */
	    }
		break;	/* end of RM_CLOSE_SS processing */
			
	case SS_TC_DELETED :
		if (g_ses_tab_ssnb[ssnbIndex].m_rssnb == 0)
		{	
			/* no routing : free the state diagram instance */
			/* Set the new state */
			g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
			iRet = 1;		/* Success */
		}
		else
		{	
			/* Send a close session request to the other side of the session */
			/* ============================================================= */
			if (g_ses_tab_ssnb[ssnbIndex].m_rtcid == g_ses_tab_ssnb[ssnbIndex].m_tcid)
			{
				/* the session is on the same transport connection : nothing to do */
				/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
				return 1;		/* Success */
			}

			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(CLOSE_SESSION_REQUEST_SIZE);
			if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - can't allocate buffer for coding SPDU\r\n");
				return 1;		/* Error but return = 1 since no allocated memory to free */
			}
                    
			/* close the session */
			/* ================= */
			xpdu.m_du.m_xpdu_close_session_response.m_status = SS_OK;
			if (pXmsg->m_bd.m_ss_tc_deleted.m_tcid == g_ses_tab_ssnb[ssnbIndex].m_rtcid)
			{	
				tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;
				ssnb = g_ses_tab_ssnb[ssnbIndex].m_ssnb;		/* first side of the session ; the other tcid is deleted  */
			}
			else	 				                                                 
			{
				tcid = g_ses_tab_ssnb[ssnbIndex].m_rtcid;
				ssnb = g_ses_tab_ssnb[ssnbIndex].m_rssnb;     /* second side of the session ; the other tcid is deleted */
			}
					
			xmsg.m_sndrcver = (SESS << 4) | TRANS;
			xmsg.m_type  = SPDU;
			xmsg.m_bd.m_spdu.m_tcid = tcid;
			xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_close_session_request, ssnb, 
									&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    		if (xmsg.m_bd.m_spdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't code a close_session_request for %d ssnb\r\n", ssnb);
				FreeXmsg(&xmsg);
				return 0;		/* Error */
			}	
            
			/* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - Can't send the close_session_request message for %d ssnb to RM Task\r\n", ssnb);
				FreeXmsg(&xmsg);
				iRet = 0;		/* Error */
			}
			else
			{
               	/* Set the timer waiting for the response for this ssnb */
				g_ses_tab_ssnb[ssnbIndex].m_timerId = SESS_SetTimer(SESS_TIMEOUT);/* do nothing if the timer can't be created */

				/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_DELETION;
				iRet = 1;		/* Success; keep the memory  */
			}	
		}
		break;	/* end of SS_TC_DELETED processing */
			
	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Active() - protocol error . event 0x%x received in %d state\r\n", evt, g_ses_tab_ssnb[ssnbIndex].m_state);
		iRet = 1;
		break;			
	}

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Active() - return,iRet=%d\r\n", iRet);
	return iRet;
}	/* end of SESS_ACTIVE state */


			

/* ======================================================================== */
/* NAME : SESS_Creation		 												*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the SESS_CREATION state					*/
/*		- The SESS Task is waiting for a create session response from the	*/
/*		module																*/
/*		- If the response is negative, the first part of the session is 	*/
/*		closed																*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram					*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_Creation(int ssnbIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;		/* return code  											*/
	xpdu_t xpdu;	/* information for SPDU		 								*/
	xmsg_t		xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Creation() - entry,ssnbIndex=%d\r\n", ssnbIndex);
	
	evt = pXmsg->m_type;
	if (SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_SESS, "SESS_Creation() - received evt=%s(0x%02X),ssnbIndex=%d\r\n", 
					XMSG_NAME(evt), evt, ssnbIndex);
					

	switch(evt) 
	{                                   
	case dutag_create_session_response :                             
       	/* kill pending timer 	*/
		SESS_Kill_Timer(ssnbIndex);

		/* Check the received parameters */
		if (g_ses_tab_ssnb[ssnbIndex].m_rssnb != xpduRcv.m_du.m_xpdu_create_session_response.m_ssnb)
			return 0;	/* Error */

		if (g_ses_tab_ssnb[ssnbIndex].m_ressId != xpduRcv.m_du.m_xpdu_create_session_response.m_ressId)
			return 0;	/* Error */

		/* Get the parameters and copy them into open_session_response */
		xpdu.m_du.m_xpdu_open_session_response.m_status = xpduRcv.m_du.m_xpdu_create_session_response.m_status;
		/* Don't check that ress_id into create_session_response is the same as the saved ress_id */
   	    xpdu.m_du.m_xpdu_open_session_response.m_ressId = g_ses_tab_ssnb[ssnbIndex].m_ressId;
			
		/* Foward the response on first part of the session to the TRANS Task */
		/* ================================================================== */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_spdu.m_pbSpdu = pXmsg->m_bd.m_spdu.m_pbSpdu;
		xmsg.m_sndrcver = (SESS << 4) | TRANS;
		xmsg.m_type  = SPDU;
		xmsg.m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;
		xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_open_session_response, 
								g_ses_tab_ssnb[ssnbIndex].m_ssnb,
								&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
   		if (xmsg.m_bd.m_spdu.m_len <= 0) 
   		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - Can't code an open_session_response for 0x%08X\r\n", 
							g_ses_tab_ssnb[ssnbIndex].m_ressId);
			return 0;		/* Error */
		}	
            
		/* Send the message */
   		if (!ITC_SendXmsg(&xmsg))
   		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - Can't send the open_session_response message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
			iRet = 0;		/* Error */
		}
		else
		{
			pXmsg->m_bd.m_spdu.m_pbSpdu = NULL;
			/* open_session_response sent */
			if (xpduRcv.m_du.m_xpdu_create_session_response.m_status == SS_OK)
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_ACTIVE; /* Set the new state */
			else
			{
				/* open_session_response(-) sent */
		    	/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
			}
			iRet = 1;		/* Success; keep the memory  */
		}
		break;	/* end of create_session_response processing */

	case SS_TMPEND :
		/* close the session */
		/* ================= */
		/* Get a buffer for SPDU message */
		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(OPEN_SESSION_RESPONSE_SIZE);
		if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
		{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - can't allocate buffer for coding SPDU\r\n");
			return 1;		/* Error but return = 1 since no allocated memory to free */
		}
				
		xpdu.m_du.m_xpdu_open_session_response.m_status = SS_NOTAVAILABLE;
        xpdu.m_du.m_xpdu_open_session_response.m_ressId = g_ses_tab_ssnb[ssnbIndex].m_ressId;
				
		xmsg.m_sndrcver = (SESS << 4) | TRANS;
		xmsg.m_type  = SPDU;
		xmsg.m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;
		xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_open_session_response, 
						g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
						&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    	if (xmsg.m_bd.m_spdu.m_len <= 0) 
    	{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - Can't code an open_session_response for 0x%08X\r\n", 
							g_ses_tab_ssnb[ssnbIndex].m_ressId);
			return 0;		/* Error */
		}	
            
		/* Send the message */
    	if (!ITC_SendXmsg(&xmsg))
    	{
			SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - Can't send the open_session_response message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
			FreeXmsg(&xmsg);
			iRet = 0;		/* Error */
		}
		else
		{
	        /* Set the new state */
			g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
			iRet = 1;		/* Success; keep the memory  */
		}
		break;	/* end of TIMESESS processing */
			
	case SS_TC_DELETED :						
		if (pXmsg->m_bd.m_ss_tc_deleted.m_tcid == g_ses_tab_ssnb[ssnbIndex].m_tcid)
		{	
			/* the deleted tcid is the first part of a session . When the distant module will respond to the */
			/* creation of the second part of the session on the second tcid, this session will be released	 */
            /* Set the new state */
			g_ses_tab_ssnb[ssnbIndex].m_state = SESS_RELEASE;
			iRet = 1;		/* Success; keep the memory  */
		}
		else
		{   
			/* the deleted tcid is the second part of a session . The session must not be opened, the first  */
			/* part of the session is closed																 */
			/* Get free buffer for SPDU message */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(OPEN_SESSION_RESPONSE_SIZE);
			if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - can't allocate buffer for coding SPDU\r\n");
				return 0;	/* Error */
			}
                    
			/* close the session */
			/* ================= */
			xpdu.m_du.m_xpdu_open_session_response.m_status = SS_NOTAVAILABLE;
    	    xpdu.m_du.m_xpdu_open_session_response.m_ressId = g_ses_tab_ssnb[ssnbIndex].m_ressId;
			
			xmsg.m_sndrcver = (SESS << 4) | TRANS;
			xmsg.m_type  = SPDU;
			xmsg.m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;
			xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_open_session_response,
									g_ses_tab_ssnb[ssnbIndex].m_ssnb, 
									&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
    		if (xmsg.m_bd.m_spdu.m_len <= 0) 
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - Can't code an open_session_response for 0x%08X\r\n", 
								g_ses_tab_ssnb[ssnbIndex].m_ressId);
				FreeXmsg(&xmsg);
				return 0;		/* Error */
			}	
            
			/* Send the message */
    		if (!ITC_SendXmsg(&xmsg))
    		{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - Can't send the open_session_response message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
				FreeXmsg(&xmsg);
				iRet = 0;		/* Error */
			}
			else
			{
               	/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
				iRet = 1;		/* Success; keep the memory  */
			}	
		}
		break;	/* end of SS_TC_DELETED processing */

	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Creation() - protocol error . event 0x%x received in %d state\r\n", evt, g_ses_tab_ssnb[ssnbIndex].m_state);
		iRet = 1;
		break;			
	}

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Creation() - return,iRet=%d\r\n", iRet);
	return iRet;
}	/* end of SESS_CREATION state */
	


/* ======================================================================== */
/* NAME : SESS_Release		 												*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the SESS_RELEASE state					*/
/*	A tcid is deleted on the first part of a session . When the response to */
/*	the creation session request will be received from the resource provider*/
/*	module, the SESS Task will release this session							*/  
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram					*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_Release(int ssnbIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;		/* return code  											*/
	xpdu_t xpdu;	/* information for SPDU		 								*/
	xmsg_t		xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Release() - entry,ssnbIndex=%d\r\n", ssnbIndex);
	
	evt = pXmsg->m_type;
	if (SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_SESS, "SESS_Release() - received evt=%s(0x%02X),ssnbIndex=%d\r\n", 
					XMSG_NAME(evt), evt, ssnbIndex);

	switch(evt) 
	{                                   
	case dutag_create_session_response :                             
       	/* kill pending timer 	*/
		SESS_Kill_Timer(ssnbIndex);
			 
		if (xpduRcv.m_du.m_xpdu_create_session_response.m_status == SS_OK)
		{ 
			/* close the session on the second part */
			/* ==================================== */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_spdu.m_pbSpdu = pXmsg->m_bd.m_spdu.m_pbSpdu;
			xmsg.m_sndrcver = (SESS << 4) | TRANS;
			xmsg.m_type  = SPDU;
			xmsg.m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_rtcid;
			xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_close_session_request,
									g_ses_tab_ssnb[ssnbIndex].m_rssnb, 
									&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
			if (xmsg.m_bd.m_spdu.m_len <= 0) 
   			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Release() - Can't code a close_session_request for 0x%08X\r\n", 
								g_ses_tab_ssnb[ssnbIndex].m_ressId);
				return 0;		/* Error */
			}	
	            
			/* Send the message */
   			if (!ITC_SendXmsg(&xmsg))
   			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Release() - Can't send the close_session_request message for %d tcid to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_tcid);
				iRet = 0;		/* Error */
			}
			else
			{
				pXmsg->m_bd.m_spdu.m_pbSpdu = NULL;
				/* Set the timer waiting for the response for this ssnb */
				g_ses_tab_ssnb[ssnbIndex].m_timerId = SESS_SetTimer(SESS_TIMEOUT);/* do nothing if the timer can't be created */
			
				/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_DELETION;
				iRet = 1;		/* Success; keep the memory  */
			}
		}	
		break;	/* end of create_session_response processing */

	case SS_TMPEND :                                    
		/* same processing that in SESS_CREATION state */
		iRet = SESS_Creation(ssnbIndex, pXmsg);
		break;	/* end of TIMESESS processing */       
			
	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Release() - protocol error . event 0x%x received in %d state\r\n", evt, g_ses_tab_ssnb[ssnbIndex].m_state);
		iRet = 1;
		break;			
	}

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Release() - return,iRet=%d\r\n", iRet);
	return iRet;
}	/* end of SESS_RELEASE state */


/* ======================================================================== */
/* NAME : SESS_Deletion		 												*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the SESS_DELETION state					*/
/*	A tcid is deleted on the first part of a session . The SESS Task has	*/
/*	close the session on the second part and is waiting for the response	*/
/*	from the TRANS Task . The RM Task is forwarded when the response is		*/
/*	received																*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram					*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_Deletion(int ssnbIndex, xmsg_t* pXmsg)
{
	int iRet;		/* return code  											*/
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Deletion() - entry,ssnbIndex=%d\r\n", ssnbIndex);
	
	evt = pXmsg->m_type;
	if (SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_SESS, "SESS_Deletion() - received evt=%s(0x%02X),ssnbIndex=%d\r\n", 
					XMSG_NAME(evt), evt, ssnbIndex);

	switch(evt)
	{                                   
	case dutag_close_session_response :                             
       	/* kill pending timer 	*/
		SESS_Kill_Timer(ssnbIndex);

       	/* Set the new state */
		g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
		iRet = 1;			/* Success */
		break;	/* end of dutag_close_session_response processing */
					
	case SS_TC_DELETED :						
       	/* kill pending timer 	*/
		SESS_Kill_Timer(ssnbIndex);

        /* Set the new state */
		g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
		iRet = 1;			/* Success */
		break;	/* end of SS_TC_DELETED processing */

	case SS_TMPEND :
         /* Set the new state */
		g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
		iRet = 1;			/* Success */
		break;		/* end of TIMESESS processing */

	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Deletion() - protocol error . event %d received in %d state\r\n", evt, g_ses_tab_ssnb[ssnbIndex].m_state);
		iRet = 1;
		break;			
	}

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Deletion() - return,iRet=%d\r\n", iRet);
	return iRet;
}	/* end of SESS_DELETION state */


/* ======================================================================== */
/* NAME : SESS_Close		 												*/
/* 									    									*/
/* DESCRIPTION : Execute the action of the SESS_CLOSE state						*/
/*		- The SESS Task is waiting for a close session response from the	*/
/*		module																*/
/*		- There are two cases :												*/
/*		  1) The close session request was made by a local resource on the 	*/
/*			 host (ex : MMI) ; There isn't routing strategy, the SESS Task	*/
/*			 forwards the response to the RM Task with RM_SS_CLOSED message */
/*		  2) The close session was made by an application and routed by the */
/*			 host to the remote resource (in SESS_ACTIVE state) . The remote		*/
/*			 resource sends the response is this state and the host must	*/
/*			 forward the response to the distant application (not to the RM */
/*			 Task)															*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*		ssnbIndex :		instance of the current state diagram					*/
/*		pXmsg :	pointer to parameters of the received xmsg					*/
/*									 										*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_Close(int ssnbIndex, xmsg_t* pXmsg)
{                                                                          
	int iRet;		/* return code  											*/
	xpdu_t xpdu;	/* information for SPDU		 								*/
	xmsg_t		xmsg;
	unsigned char 	evt = 0;
	xpdu_t 		xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_Close() - entry,ssnbIndex=%d\r\n", ssnbIndex);
	
	evt = pXmsg->m_type;
	if (SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv))
		evt = xpduRcv.m_xpdu_tag;

	SM_TRACE_INFO(TRMOD_SESS, "SESS_Close() - received evt=%s(0x%02X),ssnbIndex=%d\r\n", 
					XMSG_NAME(evt), evt, ssnbIndex);

	iRet = 1;
	
	switch(evt)
	{                                   
	case dutag_close_session_response :                             
       	/* kill pending timer 	*/
		SESS_Kill_Timer(ssnbIndex);
		//pmy, break?


	case SS_TMPEND :
		if (g_ses_tab_ssnb[ssnbIndex].m_rssnb == 0)
		{	
			/* first case . See DESCRIPTION above */
			/* forward the closing to the RM Task with RM_SS_CLOSED */
			/* ==================================================== */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_sndrcver 		= (SESS << 4) | RM;
			xmsg.m_type  		= RM_SS_CLOSED;
			xmsg.m_bd.m_rm_ss_closed.m_ssnb   = g_ses_tab_ssnb[ssnbIndex].m_ssnb;
			xmsg.m_bd.m_rm_ss_closed.m_status = SS_OK;
							
			/* Send the message */
			if (!ITC_SendXmsg(&xmsg))
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - Can't send the RM_SS_CLOSED message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
	        else
				/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
		}
		else
		{	/* second case . See DESCRIPTION above */
			/* forward the closing to the other side of the session */
			/* ==================================================== */
			/* Get free buffer for SPDU message */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(CLOSE_SESSION_RESPONSE_SIZE);
			if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - can't allocate buffer for coding SPDU\r\n");
				return 1;	/* for memory management */
			}

			xmsg.m_sndrcver	= (SESS << 4) | TRANS;
			xmsg.m_type	= SPDU;
			if (evt == SS_TMPEND)
			{
				xpdu.m_du.m_xpdu_close_session_response.m_status = SS_OK;
				/* problem with TIMESESS : unknown session to free */
				xmsg.m_bd.m_spdu.m_tcid= g_ses_tab_ssnb[ssnbIndex].m_tcid;	/* send to the first part  */		       	     	
				xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_close_session_response, 
									g_ses_tab_ssnb[ssnbIndex].m_ssnb,
									&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
			}
			else
			{
				xpdu.m_du.m_xpdu_close_session_response.m_status = xpduRcv.m_du.m_xpdu_close_session_response.m_status;
				if (xpduRcv.m_du.m_xpdu_close_session_response.m_ssnb == g_ses_tab_ssnb[ssnbIndex].m_rssnb)
				{
					xmsg.m_bd.m_spdu.m_tcid= g_ses_tab_ssnb[ssnbIndex].m_tcid;	/* send to the first part  */		       	     	
					xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_close_session_response, 
										g_ses_tab_ssnb[ssnbIndex].m_ssnb, &xpdu, 
										xmsg.m_bd.m_spdu.m_pbSpdu);
				}
				else
				{
					xmsg.m_bd.m_spdu.m_tcid= g_ses_tab_ssnb[ssnbIndex].m_rtcid;	/* send to the second part  */		       	     	
					xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_close_session_response,
											g_ses_tab_ssnb[ssnbIndex].m_rssnb,
											&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
				}
			}

  			if (xmsg.m_bd.m_spdu.m_len <= 0) 
   			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - Can't code a dutag_close_session_response for %d tcid\r\n", 
							xmsg.m_bd.m_spdu.m_tcid);
				FreeXmsg(&xmsg);
				return 1;		/* for memory management */
			}	

			/* Send the message */
			if (!ITC_SendXmsg(&xmsg))
			{
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - Can't send the dutag_close_session_response message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
				FreeXmsg(&xmsg);
				return 1;		/* for memory management */
			}
				
	        /* Set the new state */
			g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
			iRet = 1;			/* Success */
		}	
		break;		/* end of TIMESESS / close_session_response processing */
			
	case SS_TC_DELETED :
		if (g_ses_tab_ssnb[ssnbIndex].m_rssnb == 0)
		{	/* first case . See DESCRIPTION above */
			/* Send a RM_SS_CLOSED to the RM Task */
			/* ================================== */
			memset(&xmsg, 0x00, sizeof(xmsg));
			xmsg.m_sndrcver 		= (SESS << 4) | RM;
			xmsg.m_type  		= RM_SS_CLOSED;
			xmsg.m_bd.m_rm_ss_closed.m_ssnb   = g_ses_tab_ssnb[ssnbIndex].m_ssnb;
			xmsg.m_bd.m_rm_ss_closed.m_status = SS_OK;
							
			/* Send the message */
			if (!ITC_SendXmsg(&xmsg))
				SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - Can't send the RM_SS_CLOSED message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
			else	                
	          	/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
		}
		else
		{ 
			if (g_ses_tab_ssnb[ssnbIndex].m_tcid == g_ses_tab_ssnb[ssnbIndex].m_rtcid)
			{
				/* no routing strategy since the two parts of the session are on the same transport connection */
	          	/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
				return 1;		/* Success */
			}

			/* the closing part (first part) of the session is (tcid,ssnb) : cf SESS_Active */
			if (pXmsg->m_bd.m_ss_tc_deleted.m_tcid == g_ses_tab_ssnb[ssnbIndex].m_tcid)
			{	/* the first part of the session is deleted, wait for the close_session_response on the second part */
	           	/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_DELETION;
			}
			else
			{	/* the second part is deleted, a close_session_response will close the first part */
				/* Get free buffer for SPDU message */
				memset(&xmsg, 0x00, sizeof(xmsg));
				xmsg.m_bd.m_spdu.m_pbSpdu = ITC_DynAlloc(CLOSE_SESSION_RESPONSE_SIZE);
				if (xmsg.m_bd.m_spdu.m_pbSpdu == NULL)
				{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - can't allocate buffer for coding SPDU\r\n");
					return 1;		/* Error : return = 1 for memory management */
				}

				xpdu.m_du.m_xpdu_close_session_response.m_status = SS_OK;
				xmsg.m_sndrcver	= (SESS << 4) | TRANS;
				xmsg.m_type	= SPDU;
				xmsg.m_bd.m_spdu.m_tcid = g_ses_tab_ssnb[ssnbIndex].m_tcid;	/* send to the first part  */		       	     	
				xmsg.m_bd.m_spdu.m_len  = SESS_Code(dutag_close_session_response,
											g_ses_tab_ssnb[ssnbIndex].m_ssnb,
											&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
   				if (xmsg.m_bd.m_spdu.m_len <= 0) 
   				{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - Can't code a close_session_response for %d tcid\r\n", 
								xmsg.m_bd.m_spdu.m_tcid);
					FreeXmsg(&xmsg);
					return 1;		/* Error : return = 1 for memory management */
				}	    	
                	
				/* Send the message */
				if (!ITC_SendXmsg(&xmsg))
				{
					SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - Can't send the close_session_response message for %d ssnb to RM Task\r\n", g_ses_tab_ssnb[ssnbIndex].m_ssnb);
					FreeXmsg(&xmsg);
				}

				/* Set the new state */
				g_ses_tab_ssnb[ssnbIndex].m_state = SESS_IDLE;
			}
		}			
		break;		/* end of SS_TC_DELETED processing */

	default :	/* protocol error, ignore the event */
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_Close() - protocol error . event 0x%x received in %d state\r\n", evt, g_ses_tab_ssnb[ssnbIndex].m_state);
		break;			
	}

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_Close() - return,iRet=%d\r\n", iRet);
	return iRet;
}	/* end of SESS_CLOSE state */



/* ======================================================================== */
/* NAME : SESS_TCCreated						 							*/
/* 									    									*/
/* DESCRIPTION : Send a RM_TC_CREATED to the RM Task						*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*	tcid : transport connection												*/
/*									 										*/
/* OUTPUT PARAMETERS :							   							*/
/*									    									*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_TCCreated(unsigned char tcid)
{
	int		iRet;		/* Return code */
	xmsg_t	xmsg;

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_TCCreated() - entry,tcid=%d\r\n",tcid);

	/* Foward the creation of a new transport connection to the RM Task */
	/* ================================================================ */
	memset(&xmsg, 0x00, sizeof(xmsg));
	xmsg.m_sndrcver    = (SESS << 4) | RM;
	xmsg.m_type     = RM_TC_CREATED;
    xmsg.m_bd.m_rm_tc_created.m_tcid = tcid;
            
	/* Send the message */
    if (!ITC_SendXmsg(&xmsg))
    {
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_TCCreated() - Can't send the RM_TC_CREATED message for %d tcid to RM Task\r\n", tcid);
		iRet = 0;		/* Error */
	}
	else
		iRet = 1;		/* Success */

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_TCCreated() - return,iRet=%d\r\n",iRet);
	return iRet;
}



/* ======================================================================== */
/* NAME : SESS_TCDeleted						 							*/
/* 									    									*/
/* DESCRIPTION : Send a RM_TC_DELETED to the RM Task						*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*	tcid : transport connection												*/
/*									 										*/
/* OUTPUT PARAMETERS :							   							*/
/*									    									*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_TCDeleted(unsigned char tcid)
{
	int iRet;		/* Return code */
	xmsg_t	xmsg;

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_TCDeleted() - entry,tcid=%d\r\n",tcid);

	/* Foward the deletion of the transport connection to the RM Task */
	/* ============================================================== */	
	memset(&xmsg, 0x00, sizeof(xmsg));
	xmsg.m_sndrcver      = (SESS << 4) | RM;
	xmsg.m_type       = RM_TC_DELETED;
    xmsg.m_bd.m_rm_tc_deleted.m_tcid = tcid;
            
	/* Send the message */
    if (!ITC_SendXmsg(&xmsg))
	{
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_TCCreated() - SESS_TCDeleted : Can't send the RM_TC_DELETED message for %d tcid to RM Task\r\n", tcid);
		iRet = 0;		/* Error */
	}
	else
		iRet = 1;		/* Success */

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_TCDeleted() - return,iRet=%d\r\n",iRet);
	return iRet;
}

	

/* ======================================================================== */
/* NAME : SESS_DeleteTC							 							*/
/* 									    									*/
/* DESCRIPTION : Send a SS_DELETE_TC to the TRANS Task						*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*	tcid : transport connection												*/
/*									 										*/
/* OUTPUT PARAMETERS :							   							*/
/*									    									*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
int SESS_DeleteTC(unsigned char tcid)
{
	int		iRet;		/* Return code */
	xmsg_t	xmsg;

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_DeleteTC() - entry,tcid=%d\r\n",tcid);

	/* Foward the request to delete the transport connection to the TRANS Task */
	/* ======================================================================= */
	memset(&xmsg, 0x00, sizeof(xmsg));
	xmsg.m_sndrcver  = (SESS << 4) | TRANS;
	xmsg.m_type   = SS_DELETE_TC;
    xmsg.m_bd.m_tran_ssdeletetc.m_tcid = tcid;
            
    /* Send the message */
	if (!ITC_SendXmsg(&xmsg))
	{
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_DeleteTC() - Can't send the SS_DELETE_TC message for %d tcid to TRANS Task\r\n", tcid);
		iRet = 0;		/* Error */
	}
	else
		/* No timeout : a transport timeout is managed into transport layer */
		iRet = 1;		/* Success */

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_DeleteTC() - return,iRet=%d\r\n",iRet);
	return iRet;
}


/* ======================================================================== */
/* NAME : SESS_NotOpen							 							*/
/* 									    									*/
/* DESCRIPTION : Send an open_session_response(-) to the RM Task				*/
/* 									    									*/
/* INPUT PARAMETERS :							    						*/
/*									 										*/
/* OUTPUT PARAMETERS :							   							*/
/*									    									*/
/* RETURN CODE								    							*/
/*		1 : Success															*/
/*		0 : Error															*/
/*									  										*/
/* ======================================================================== */
void SESS_NotOpen(xmsg_t* pXmsg)
{
	xpdu_t 	xpdu;
	xmsg_t		xmsg;
	xpdu_t 	xpduRcv;		

	SM_TRACE_ENTRY(TRMOD_SESS, "SESS_NotOpen() - entry,pXmsg=0x%08X\r\n", pXmsg);
	
	SESS_XmsgDecode(pXmsg, NULL, NULL, &xpduRcv);
	SM_ASSERT(xpduRcv.m_xpdu_tag == dutag_open_session_request);

	/* can't open the session : resource not available */
	/* =============================================== */      
	memset(&xpdu, 0x00, sizeof(xpdu));
	xpdu.m_du.m_xpdu_open_session_response.m_status = SS_NOTAVAILABLE;
	xpdu.m_du.m_xpdu_open_session_response.m_ressId = xpduRcv.m_du.m_xpdu_open_session_request.m_ressId;
				
	/* Take the buffer used for open_session_request   */
	memset(&xmsg, 0x00, sizeof(xmsg));
	xmsg.m_bd.m_spdu.m_pbSpdu = pXmsg->m_bd.m_spdu.m_pbSpdu;
	xmsg.m_sndrcver = (SESS << 4) | TRANS;
	xmsg.m_type  = SPDU;
	xmsg.m_bd.m_spdu.m_len = SESS_Code(dutag_open_session_response, 0, 
							&xpdu, xmsg.m_bd.m_spdu.m_pbSpdu);
	if (xmsg.m_bd.m_spdu.m_len <= 0) 
	{
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_NotOpen() - Can't code an open_session_response for 0x%08X\r\n", 
						xpdu.m_du.m_xpdu_open_session_response.m_ressId);
		return;
	}	
            
    /* Send the message */
	if (!ITC_SendXmsg(&xmsg))
    {
		SM_TRACE_ERROR(TRMOD_SESS, "SESS_NotOpen() - Can't send the open_session_response "
					"message for %d tcid to RM Task\r\n", pXmsg->m_bd.m_spdu.m_tcid);
		return;
	}

	pXmsg->m_bd.m_spdu.m_pbSpdu = NULL;

	SM_TRACE_RETURN(TRMOD_SESS, "SESS_NotOpen() - return\r\n");
}
